/*
 * @Description: 响应
 * @Version: 1.0
 * @Autor: JiaJun Wu
 * @Date: 2021-09-07 12:00:05
 * @LastEditors: JiaJun Wu
 * @LastEditTime: 2021-09-16 12:44:29
 */
use rocket::http::{ContentType, Status};
use rocket::response;
use rocket::response::{Responder, Response};
use rocket::serde::json::{serde_json::json, Value};
use rocket::{serde::Serialize, *};

#[derive(Debug, Clone)]
pub struct ApiResult<T> {
    pub body: Option<T>,
    // 操作是否成功 true.成功 / false.失败
    pub success: bool,
    // 响应信息
    pub message: String,
    // 页数
    pub page: Option<i64>,
    // 每页最大值
    pub limit: Option<i64>,
    // 查询内容总数
    pub total: Option<i64>,
    pub code: Status,
}

impl<T: Serialize> ApiResult<T> {
    pub fn new() -> Self {
        Self {
            body: None,
            success: false,
            message: "".to_string(),
            page: None,
            limit: None,
            total: None,
            code: Status::new(200),
        }
    }

    pub fn err(message: String) -> Self {
        Self {
            code: Status::BadRequest,
            success: false,
            message: message,
            page: None,
            limit: None,
            total: None,
            body: None,
        }
    }
    pub fn internal_err(message: String) -> Self {
        Self {
            code: Status::InternalServerError,
            success: false,
            message: format!("内部服务器错误,{:?}", message),
            page: None,
            limit: None,
            total: None,
            body: None,
        }
    }

    fn to_json(&self) -> Value {
        match &self.body {
            Some(body) => json!({
                "code":self.code.code,
                "success": self.success,
                "message": self.message,
                "page": self.page.unwrap_or(0),
                "limit": self.limit.unwrap_or(0),
                "total": self.total.unwrap_or(0),
                "body":body
            }),
            None => json!({
                "code":self.code.code,
                "success": self.success,
                "message": self.message,
                "page": self.page.unwrap_or(0),
                "limit": self.limit.unwrap_or(0),
                "total": self.total.unwrap_or(0),
                "body":Value::Null
            }),
        }
    }
}

impl<'r, T: Serialize> Responder<'r, 'static> for ApiResult<T> {
    fn respond_to(self, req: &Request) -> response::Result<'static> {
        Response::build_from(self.to_json().respond_to(&req).unwrap())
            .status(self.code)
            .header(ContentType::JSON)
            .ok()
    }
}
